package com.github.kezhenxu94.playground.java.concurrent.executor;

import java.util.Random;
import java.util.concurrent.CompletionService;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 * <pre>
 * 
 * {@link Executor} 接口将任务的提交和任务的执行相解耦,
 * 而 {@link CompletionService} 接口则将任务的结果和
 * 如何获取该结果相解耦, 该接口提供了以下几个方法方便提取任
 * 务的执行结果.
 * 
 * 1. {@link CompletionService#take()} 获取并移除
 * 代表即将完成的任务的 {@link Future} 对象, 如果没有
 * 即将完成的任务, 将阻塞等待.
 * 
 * 2. {@link CompletionService#poll()} 获取并移除
 * 代表即将完成的任务的 {@link Future} 对象, 如果没有
 * 即将完成的任务, 将返回 null.
 * 
 * 3. {@link CompletionService#poll(long, TimeUnit)} 
 * 在规定的时间内获取并移除代表即将完成的任务的 {@link Future} 
 * 对象, 如果指定时间内没有即将完成的任务, 返回 null.
 * 
 * </pre>
 * 
 * @author kezhenxu
 *
 */
public class StudyCompletionService {
	
	public static void main(String[] args) throws Exception {
		ExecutorService executor = Executors.newFixedThreadPool(10);
		CompletionService<String> service = new ExecutorCompletionService<>(executor);
		Random random = new Random();
		for (int i = 0; i < 100; i++) {
			service.submit(() -> {
				Thread.sleep(random.nextInt(5000)); // 模拟延时操作
				return "Hello this is " + Thread.currentThread();
			});
		}
		for (int i = 0; i < 100; i++) {
			Future<String> result = service.take();
			System.out.println(result.get());
		}
		
		executor.shutdown();
	}
}
